#region Imported Namespaces


using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;

using WtfManager.HierarchicalData;
using WtfManager.WindowsNative.Shell32;

using FileInfo=WtfManager.WindowsNative.Shell32.FileInfo;


#endregion


namespace WtfManager.FileManager
{
  ///<summary>
  /// Describes and manipulates a file system folder.
  ///</summary>
  public class FileSystemFolder: FileSystemItem
  {
    #region Fields


    private DirectoryInfo _directoryInfo;


    #endregion


    #region Constructors/Finalizers


    ///<summary>
    /// Default FileSystemFolder constructor.
    ///</summary>
    ///<param name="name"></param>
    protected FileSystemFolder(string name)
    {
      Name = name;
    }


    #endregion


    #region Properties/Indexers


    public override bool IsMovable
    {
      get
      {
        return true;
      }
    }

    private DirectoryInfo DirectoryInfo
    {
      get
      {
        if (_directoryInfo == null)
        {
          _directoryInfo = new DirectoryInfo(GetFileSystemPath());
        }

        return _directoryInfo;
      }
    }

    public override bool IsFile
    {
      get
      {
        return false;
      }
    }

    public override bool IsHidden
    {
      get
      {
        return (DirectoryInfo.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden;
      }
    }


    #endregion


    #region Methods


    protected override void OnRefresh()
    {
      _directoryInfo = null;

      try
      {
        FileSystemInfo[] fileSystemInfos = DirectoryInfo.GetFileSystemInfos();

        RemovedUnexistingItems(fileSystemInfos);
        AddNewItems(fileSystemInfos);
      }
      catch (Exception)
      {
        return;
      }
    }


    private void AddNewItems(IEnumerable<FileSystemInfo> fileSystemInfos)
    {
      foreach (FileSystemInfo fileSystemInfo in fileSystemInfos)
      {
        string fileName = fileSystemInfo.Name;

        if (Children.Contains(fileName))
        {
          continue;
        }

        if (fileSystemInfo is DirectoryInfo)
        {
          var folder = new FileSystemFolder(fileName);
          AddChild(folder);
        }

        if (fileSystemInfo is System.IO.FileInfo)
        {
          var file = new FileSystemFile(fileName);
          AddChild(file);
        }
      }
    }


    private void RemovedUnexistingItems(IEnumerable<FileSystemInfo> fileSystemInfos)
    {
      var itemsToRemove = new List<TreeItem>();

      foreach (TreeItem item in Children)
      {
        if (!ItemExists(fileSystemInfos, item))
        {
          itemsToRemove.Add(item);
        }
      }

      foreach (TreeItem item in itemsToRemove)
      {
        RemoveChild(item);
      }
    }


    private static bool ItemExists(IEnumerable<FileSystemInfo> fileSystemInfos, TreeItem item)
    {
      foreach (FileSystemInfo info in fileSystemInfos)
      {
        if (info.Name == item.Name)
        {
          return true;
        }
      }

      return false;
    }


    ///<summary>
    /// Gets an icon of a file system item.
    ///</summary>
    ///<returns>Returns <see cref="Icon"/>.</returns>
    protected override Icon GetIcon(FileInfo flags)
    {
      flags |= FileInfo.SHGFI_USEFILEATTRIBUTES;
      var pidl = GetPidl(flags);

      //var overlayIndex = pidl.GetIconOverlayIndex();

      return pidl.Icon;
    }




    ///<summary>
    /// Gets file system path of an item.
    ///</summary>
    ///<returns>a string containing file system path of an item.</returns>
    protected override string GetFileSystemPath()
    {
      return base.GetFileSystemPath() + "\\";
    }


    #endregion
  }
}